package com.devenv.common.plugin;

import com.devenv.core.dto.AuthRequest;
import com.devenv.core.dto.AuthResult;
import com.devenv.core.dto.UserInfo;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

/**
 * 认证提供者接口
 * <p>
 * 定义了统一的认证服务接口，支持多种认证方式的插件化扩展。
 * 包括用户名密码认证、第三方OAuth认证（如微信、QQ等）等。
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
public interface IAuthProvider {

    /**
     * 获取认证提供者的名称
     * <p>
     * 用于标识不同的认证提供者，如："local", "wechat", "qq"等
     * </p>
     * 
     * @return 认证提供者名称，不能为null
     */
    @NonNull
    String getName();

    /**
     * 获取认证提供者的显示名称
     * <p>
     * 用于在UI界面显示给用户，如："本地认证", "微信登录", "QQ登录"等
     * </p>
     * 
     * @return 认证提供者显示名称，不能为null
     */
    @NonNull
    String getDisplayName();

    /**
     * 检查认证提供者是否可用
     * <p>
     * 用于检查认证服务是否正常工作，包括网络连接、配置信息等
     * </p>
     * 
     * @return true表示可用，false表示不可用
     */
    boolean isAvailable();

    /**
     * 执行用户认证
     * <p>
     * 根据认证请求进行用户身份验证，返回认证结果
     * </p>
     * 
     * @param request 认证请求，包含认证所需的参数，不能为null
     * @return 认证结果，包含认证状态、用户信息、token等，不能为null
     * @throws AuthException 认证过程中出现错误时抛出
     */
    @NonNull
    AuthResult authenticate(@NonNull AuthRequest request) throws AuthException;

    /**
     * 根据token获取用户信息
     * <p>
     * 验证token的有效性并获取对应的用户信息
     * </p>
     * 
     * @param token 用户认证token，不能为null或空字符串
     * @return 用户信息，token无效时返回null
     * @throws AuthException token验证过程中出现错误时抛出
     */
    @Nullable
    UserInfo getUserInfo(@NonNull String token) throws AuthException;

    /**
     * 验证token是否有效
     * <p>
     * 检查token的有效性，包括过期时间、签名等
     * </p>
     * 
     * @param token 待验证的token，不能为null或空字符串
     * @return true表示token有效，false表示token无效
     * @throws AuthException token验证过程中出现错误时抛出
     */
    boolean validateToken(@NonNull String token) throws AuthException;

    /**
     * 刷新访问token
     * <p>
     * 使用刷新token获取新的访问token，延长用户登录状态
     * </p>
     * 
     * @param refreshToken 刷新token，不能为null或空字符串
     * @return 新的认证结果，包含新的访问token，刷新失败时返回null
     * @throws AuthException 刷新过程中出现错误时抛出
     * @since 1.0.0
     */
    @Nullable
    AuthResult refreshToken(@NonNull String refreshToken) throws AuthException;

    /**
     * 注销用户登录
     * <p>
     * 使指定的token失效，清除用户登录状态
     * </p>
     * 
     * @param token 待注销的token，不能为null或空字符串
     * @return true表示注销成功，false表示注销失败或token已失效
     * @throws AuthException 注销过程中出现错误时抛出
     * @since 1.0.0
     */
    boolean logout(@NonNull String token) throws AuthException;

    /**
     * 获取认证提供者的配置信息
     * <p>
     * 返回当前认证提供者的配置状态，用于系统监控和故障排查
     * </p>
     * 
     * @return 配置信息的键值对，不包含敏感信息，不能为null
     * @since 1.0.0
     */
    @NonNull
    java.util.Map<String, Object> getConfigInfo();

    /**
     * 认证异常类
     * <p>
     * 认证过程中出现的各种异常情况
     * </p>
     */
    class AuthException extends Exception {
        
        private final String errorCode;
        
        public AuthException(String message) {
            super(message);
            this.errorCode = "AUTH_ERROR";
        }
        
        public AuthException(String message, Throwable cause) {
            super(message, cause);
            this.errorCode = "AUTH_ERROR";
        }
        
        public AuthException(String errorCode, String message) {
            super(message);
            this.errorCode = errorCode;
        }
        
        public AuthException(String errorCode, String message, Throwable cause) {
            super(message, cause);
            this.errorCode = errorCode;
        }
        
        public String getErrorCode() {
            return errorCode;
        }
    }
}
